"""
Case Type   : datakit并行安装数据库
Case Name   : 创建并行安装任务，选择安装CM工具，选择成功
Create At   : 2025/06/11
Owner       : @ningyali
Description :
    1.导入服务器
    2.添加用户
        2.1:主节点添加用户
        2.2:备1节点添加用户
        2.3:备2节点添加用户
        2.4:主节点获取hostUserId
        2.5:备1节点获取hostUserId
        2.6:备2节点获取hostUserId
    3.获取安装包，存放本地
    4.上传安装包
    5.创建并行安装任务，安装包选择第4步上传的包
        5.1:获取packageId
        5.2:创建clusterTask，选择安装CM工具
        5.3:创建node1,CM工具配置
        5.4:创建node2,CM工具配置
        5.5:创建node3,CM工具配置
    6.查看草稿箱中并行安装任务列表
Expect      :
    1.成功
    2.成功
        2.1:成功
        2.2:成功
        2.3:成功
        2.4:成功
        2.5:成功
        2.6:成功
    3.执行成功
    4.执行成功
    5.创建任务成功
        5.1:执行成功
        5.2:执行成功
        5.3:执行成功
        5.4:执行成功
        5.5:执行成功
    6.可查看到第5步创建的任务
History     :
"""

import os
import subprocess
import unittest

import requests
from testcase.utils.Common import Common
from testcase.utils.CommonDatakit import CommonDatakit
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Logger import Logger
from testcase.utils.datakit_api.BaseOpsApi import BaseOpsApi
from testcase.utils.datakit_api.CommonApi import CommonApi
from yat.test import Node
from yat.test import macro


class Tools(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f"-----{os.path.basename(__file__)} start-----")
        self.com_sh = CommonSH()
        self.common = Common('PrimaryRoot')
        self.pri_node = Node('PrimaryDbUser')
        self.pri_node_root = Node('PrimaryRoot')
        self.sta1_node_root = Node('Standby1Root')
        self.sta2_node_root = Node('Standby2Root')
        self.host_list = [self.pri_node_root, self.sta1_node_root,
                          self.sta2_node_root]
        self.user = 'Batch_0036'
        self.db_version = macro.DATAKIT_RECENT_DB_VERSION
        self.pkg_name = f'pkg_{self.user}'
        self.cluster_name = f'cluster_{self.user}'
        self.pkg_version = 'ENTERPRISE'

        text = '----prestep1:获取token expect:执行成功----'
        self.log.info(text)
        self.token = self.com_sh.get_token_value(macro.DATAKIT_PASSWD)
        self.log.info(self.token)
        self.assertNotIn("error", self.token.lower(), f'执行失败:{text}')

        self.com_api = CommonApi(self.token)
        self.base_ops_api = BaseOpsApi(self.token)
        self.datakit_sh = CommonDatakit(self.token)
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token}

        text = '----prestep2:获取当前os信息 expect:执行成功----'
        self.log.info(text)
        self.os_info = self.datakit_sh.get_os_info(self.pri_node_root)
        self.pkg_url = self.datakit_sh.join_pkg_url(
            self.pri_node_root, self.db_version, self.pkg_version)
        self.complete_pkg_url = f'{macro.DATAKIT_GET_PKG_URL}/{self.pkg_url}'
        self.save_pkg_path = os.path.join(
            macro.DB_BACKUP_PATH, os.path.basename(self.pkg_url))

    def test_batch_installation(self):
        text = '----step1:导入服务器 expect:成功----'
        self.log.info(text)
        self.datakit_sh.import_host(self.host_list)
        self.common.create_user(self.pri_node_root, self.user)

        text = '----step2:添加用户 expect:成功----'
        self.log.info(text)
        text = '----step2.1:主节点添加用户 expect:成功----'
        self.log.info(text)
        res1 = self.com_api.get_host_page(name=self.pri_node_root.ssh_host)
        self.pri_host_id = res1.json()['rows'][0]['hostId']
        data = {"hostId": self.pri_host_id,
                "username": self.user,
                "password": f"{macro.COMMON_PASSWD}"}
        res2 = self.com_api.post_hostUser(data)
        self.log.info(f'res2.json():{res2.json()}')
        self.assertEqual(200, res2.json()['code'], '添加用户失败')

        text = '----step2.2:备1节点添加用户 expect:成功----'
        self.log.info(text)
        res1 = self.com_api.get_host_page(name=self.sta1_node_root.ssh_host)
        self.sta1_host_id = res1.json()['rows'][0]['hostId']
        data = {"hostId": self.sta1_host_id,
                "username": self.user,
                "password": f"{macro.COMMON_PASSWD}"}
        res2 = self.com_api.post_hostUser(data)
        self.log.info(f'res2.json():{res2.json()}')
        self.assertEqual(200, res2.json()['code'], '添加用户失败')

        text = '----step2.3:备2节点添加用户 expect:成功----'
        self.log.info(text)
        res1 = self.com_api.get_host_page(name=self.sta2_node_root.ssh_host)
        self.sta2_host_id = res1.json()['rows'][0]['hostId']
        data = {"hostId": self.sta2_host_id,
                "username": self.user,
                "password": f"{macro.COMMON_PASSWD}"}
        res2 = self.com_api.post_hostUser(data)
        self.log.info(f'res2.json():{res2.json()}')
        self.assertEqual(200, res2.json()['code'], '添加用户失败')

        text = '----step2.4:主节点获取hostUserId expect:成功----'
        self.log.info(text)
        api = f'/plugins/base-ops/clusterTask/hostUser/{self.pri_host_id}'
        response = requests.get(url=self.base_ops_api.ip + api,
                                headers=self.headers, verify=False)
        self.log.info(f'response.text:{response.text}')
        self.pri_host_user_id = None
        for item in response.json()["data"]:
            if item.get('hostId', None) == self.pri_host_id:
                self.pri_host_user_id = item.get('hostUserId')
        self.log.info(f'pri_host_user_id:{self.pri_host_user_id}')

        text = '----step2.5:备1节点获取hostUserId expect:成功----'
        self.log.info(text)
        api = f'/plugins/base-ops/clusterTask/hostUser/{self.sta1_host_id}'
        response = requests.get(url=self.base_ops_api.ip + api,
                                headers=self.headers, verify=False)
        self.log.info(f'response.text:{response.text}')
        self.sta1_host_user_id = None
        for item in response.json()["data"]:
            if item.get('hostId', None) == self.sta1_host_id:
                self.sta1_host_user_id = item.get('hostUserId')
        self.log.info(f'sta1_host_user_id:{self.sta1_host_user_id}')

        text = '----step2.6:备2节点获取hostUserId expect:成功----'
        self.log.info(text)
        api = f'/plugins/base-ops/clusterTask/hostUser/{self.sta2_host_id}'
        response = requests.get(url=self.base_ops_api.ip + api,
                                headers=self.headers, verify=False)
        self.log.info(f'response.text:{response.text}')
        self.sta2_host_user_id = None
        for item in response.json()["data"]:
            if item.get('hostId', None) == self.sta2_host_id:
                self.sta2_host_user_id = item.get('hostUserId')
        self.log.info(f'sta2_host_user_id:{self.sta2_host_user_id}')

        text = '----step3:获取安装包，存放本地 expect:执行成功----'
        self.log.info(text)
        wget_cmd = f'wget -P {macro.DB_BACKUP_PATH} -nv {self.complete_pkg_url}'
        ls_cmd = f'ls {macro.DB_BACKUP_PATH}|' \
                 f'grep "{os.path.basename(self.pkg_url)}"'
        self.log.info(wget_cmd)
        wget_res = subprocess.getoutput(wget_cmd)
        self.log.info(wget_res)
        self.assertNotIn('error', wget_res.lower(), f'执行成功:{text}')

        self.log.info(ls_cmd)
        ls_res = subprocess.getoutput(ls_cmd)
        self.log.info(ls_res)
        self.assertGreater(len(ls_res.strip()), 0, f'执行成功:{text}')

        text = '----step4:上传安装包 expect:执行成功----'
        self.log.info(text)
        api = '/plugins/base-ops/installPackageManager/v2/save/upload/'
        file_object = {
            "name": (None, self.pkg_name, None),
            "os": (None, self.os_info['os'], None),
            "osVersion": (None, self.os_info['os_version'], None),
            "cpuArch": (None, self.os_info['cpu_arch'], None),
            "packageVersionNum": (None, self.db_version, None),
            "packageVersion": (None, self.pkg_version, None),
            "packageUrl": (None, self.complete_pkg_url, None),
            "uploadFile": (os.path.basename(self.pkg_url),
                           open(self.save_pkg_path, 'rb'),
                           'application/gzip')
        }
        headers = {"Authorization": "Bearer " + self.token}
        response = requests.post(
            url=self.base_ops_api.ip + api, files=file_object,
            headers=headers, verify=False)
        self.log.info(f'response.text:{response.text}')
        self.assertEqual(response.json()["code"], 200, f'执行成功:{text}')

        text = '----step5:创建并行安装任务，安装包选择第4步上传的包 expect:创建任务成功----'
        self.log.info(text)
        text = '----step5.1:获取packageId expect:执行成功----'
        self.log.info(text)
        api = f'/plugins/base-ops/installPackageManager/v2/list/package'
        data = {"name": "",
                "os": self.os_info['os'],
                "osVersion": self.os_info['os_version'],
                "cpuArch": self.os_info['cpu_arch'],
                "openGaussVersion": self.pkg_version,
                "openGaussVersionNum": self.db_version}
        response = requests.post(
            url=self.base_ops_api.ip + api, json=data, headers=self.headers,
            verify=False)
        self.log.info(f'response.text:{response.text}')
        self.package_id = response.json()[0]["packageId"]
        self.log.info(f'packageId:{self.package_id}')

        text = '----step5.2:创建clusterTask，选择安装CM工具 expect:执行成功----'
        self.log.info(text)
        unused_port = self.common.get_not_used_port(self.pri_node_root)
        cluster_api = f'/plugins/base-ops/clusterTask/create'
        cluster_data = {
            "hostId": self.pri_host_id,
            "hostUserId": self.pri_host_user_id,
            "os": self.os_info['os'],
            "cpuArch": self.os_info['cpu_arch'],
            "version": self.pkg_version,
            "versionNum": self.db_version,
            "packageName": self.pkg_name,
            "packageId": self.package_id,
            "clusterName": self.cluster_name,
            f"databaseUsername": self.user,
            "databasePassword": macro.COMMON_PASSWD,
            "port": unused_port,
            "installPackagePath": "/opt/dk_batch_install/software/openGauss",
            "installPath": "/opt/dk_batch_install/openGauss/install/app",
            "logPath": "/opt/dk_batch_install/openGauss/log/omm",
            "tmpPath": "/opt/dk_batch_install/openGauss/tmp",
            "omToolsPath": "/opt/dk_batch_install/openGauss/install/om",
            "corePath": "/opt/dk_batch_install/openGauss/corefile",
            "envPath": f'/home/{self.user}/gaussdb.bashrc',
            "enableCmTool": True,
            "enableGenerateEnvironmentVariableFile": True,
            "xmlConfigPath": "",
            "deployType": "CLUSTER"}
        response = requests.post(
            url=self.base_ops_api.ip + cluster_api, json=cluster_data,
            headers=self.headers, verify=False)
        self.log.info(f'response.text:{response.text}')
        self.cluster_id = response.json()["msg"]
        self.log.info(f'clusterId:{self.cluster_id}')
        self.assertEqual(response.json()["code"], 200, f'执行成功:{text}')

        text = '----step5.3:创建node1,CM工具配置 expect:执行成功----'
        self.log.info(text)
        unused_port = self.common.get_not_used_port(self.pri_node_root)
        api = '/plugins/base-ops/cluster/task/node/create'
        node_data = {"clusterNodeId": "",
                     "clusterId": self.cluster_id,
                     "hostId": self.pri_host_id,
                     "hostUserId": self.pri_host_user_id,
                     "nodeType": "MASTER",
                     "dataPath": "/opt/dk_batch_install/openGauss/data/dn",
                     "azOwner": "",
                     "azPriority": "",
                     "isCMMaster": True,
                     "cmDataPath": "/opt/dk_batch_install/openGauss/cm_data",
                     "cmPort": unused_port}
        response = requests.post(
            url=self.base_ops_api.ip + api, json=node_data,
            headers=self.headers, verify=False)
        self.log.info(f'response.text:{response.text}')
        self.assertEqual(response.json()["code"], 200, f'执行成功:{text}')

        text = '----step5.4:创建node2,CM工具配置 expect:执行成功----'
        self.log.info(text)
        api = '/plugins/base-ops/cluster/task/node/create'
        node_data = {"clusterNodeId": "",
                     "clusterId": self.cluster_id,
                     "hostId": self.sta1_host_id,
                     "hostUserId": self.sta1_host_user_id,
                     "nodeType": "SLAVE",
                     "dataPath": "/opt/dk_batch_install/openGauss/data/dn",
                     "azOwner": "",
                     "azPriority": "",
                     "isCMMaster": False,
                     "cmDataPath": "/opt/dk_batch_install/openGauss/cm_data",
                     "cmPort": unused_port}
        response = requests.post(
            url=self.base_ops_api.ip + api, json=node_data,
            headers=self.headers, verify=False)
        self.log.info(f'response.text:{response.text}')
        self.assertEqual(response.json()["code"], 200, f'执行成功:{text}')

        text = '----step5.5:创建node3,CM工具配置 expect:执行成功----'
        self.log.info(text)
        api = '/plugins/base-ops/cluster/task/node/create'
        node_data = {"clusterNodeId": "",
                     "clusterId": self.cluster_id,
                     "hostId": self.sta2_host_id,
                     "hostUserId": self.sta2_host_user_id,
                     "nodeType": "SLAVE",
                     "dataPath": "/opt/dk_batch_install/openGauss/data/dn",
                     "azOwner": "",
                     "azPriority": "",
                     "isCMMaster": False,
                     "cmDataPath": "/opt/dk_batch_install/openGauss/cm_data",
                     "cmPort": unused_port}
        response = requests.post(
            url=self.base_ops_api.ip + api, json=node_data,
            headers=self.headers, verify=False)
        self.log.info(f'response.text:{response.text}')
        self.assertEqual(response.json()["code"], 200, f'执行成功:{text}')

        text = '----step6:查看草稿箱中并行安装任务列表 expect:可查看到第5步创建的任务----'
        self.log.info(text)
        api = f'/plugins/base-ops/clusterTask/page?' \
              f'name=&openGaussVersion=&pageNum=1&pageSize=10'
        data = {"os": None, "cpuArch": None, "openGaussVersion": None,
                "openGaussVersionNum": None, "status": "DRAFT"}
        response = requests.post(
            url=self.base_ops_api.ip + api, json=data, headers=self.headers,
            verify=False)
        self.log.info(f'response.text:{response.text}')
        self.assertEqual(response.json()["rows"][0]["clusterId"],
                         self.cluster_id, f'执行成功:{text}')

    def tearDown(self):
        text1 = '----step7:删除草稿箱中并行安装任务列表 expect:执行成功----'
        self.log.info(text1)
        api = '/plugins/base-ops/clusterTask/delete'
        data = [self.cluster_id]
        response1 = requests.post(
            url=self.base_ops_api.ip + api, json=data, headers=self.headers,
            verify=False)
        self.log.info(f'response.text:{response1.text}')

        text2 = '----step8:删除安装包 expect:执行成功----'
        self.log.info(text2)
        api = '/plugins/base-ops/installPackageManager/v2/delete/package'
        data = [self.package_id]
        response2 = requests.post(
            url=self.base_ops_api.ip + api, json=data, headers=self.headers,
            verify=False)
        self.log.info(f'response2.text:{response2.text}')

        rm_cmd = f'rm -rf {self.save_pkg_path}'
        self.log.info(rm_cmd)
        rm_res = subprocess.getoutput(rm_cmd)
        self.log.info(rm_res)

        text3 = '----step9:清理环境 expect:成功----'
        self.log.info(text3)
        self.datakit_sh.delete_host()
        self.common.get_sh_result(self.pri_node_root, f'userdel -r {self.user}')

        self.assertEqual(response1.json()["code"], 200, f'执行成功:{text1}')
        self.assertEqual(response2.json()["code"], 200, f'执行成功:{text2}')
        self.assertNotIn('error', rm_res.lower(), f'执行成功:{text2}')
        self.log.info(f"-----{os.path.basename(__file__)} finsh-----")
